package org.kymjs.kjframe.demo;

import static org.kymjs.kjframe.common.Constant.CONTROL_BASE;
import static org.kymjs.kjframe.common.Constant.PORT_LOCAL_SERVER;
import static org.kymjs.kjframe.ui.ViewInject.toast;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;

import com.yanzhenjie.andserver.AndServer;
import com.yanzhenjie.andserver.Server;

import org.json.JSONException;
import org.json.JSONObject;
import org.kymjs.kjframe.KJHttp;
import org.kymjs.kjframe.http.HttpCallBack;
import org.kymjs.kjframe.utils.WebsocketClient;
import org.webrtc.IceCandidate;

import java.util.concurrent.TimeUnit;

public class AppService extends Service {
    private static final String TAG = AppService.class.getSimpleName();
    private static final int SERVICE_ID = 101;
    private static final String NOTIFICATION_CHANNEL_ID = "WebScreenServiceChannel";
    private static final String NOTIFICATION_CHANNEL_NAME = "WebScreen notification channel";
    private static final String TYPE_VALUE_INVITE_CODE = "infoinvitecode";
    private static final String NOTIFICATION_TITLE = "应用录制正在进行";
    private static final String NOTIFICATION_CONTENT = "点击去停止";
    private static final String MOUSE_PARAM_X = "x";
    private static final String MOUSE_PARAM_Y = "y";
    private static boolean isRunning = false;
    private final IBinder iBinder = new AppServiceBinder();
    private Intent intent;
    private Context context;
    private WebRtcManager webRtcManager = null;
    private SignalClient signalClient = null;
    private HeartClient heartClient = null;
    private boolean isCastScreenRunning = false;
    private KJHttp httpClient = new KJHttp();
    private SettingsHelper settingsHelper;
    private String tempInviteCode = null;
    private boolean allowInviteCode = false;

    @Override
    public void onCreate() {
        Log.d(TAG, "Service created");
    }

    @Override
    public void onDestroy() {
        Log.d(TAG, "Service destroyed");
        serverStop();
        isRunning = false;
    }

    public static boolean isServiceRunning() {
        return isRunning;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        settingsHelper = new SettingsHelper(getApplicationContext(),null);
        Intent notificationIntent = new Intent(this, MainActivity.class);
        notificationIntent.setAction(Intent.ACTION_MAIN);
        notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);

        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

        String channelId = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
                createNotificationChannel() : "";
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this,
                channelId);
        Notification notification = notificationBuilder.setOngoing(true)
                .setContentTitle(NOTIFICATION_TITLE)
                .setContentText(NOTIFICATION_CONTENT)
                .setSmallIcon(R.drawable.ic_stat_name)
                .setCategory(NotificationCompat.CATEGORY_SERVICE)
                .setContentIntent(pendingIntent)
                .build();

        startForeground(SERVICE_ID, notification);

        Log.d(TAG, "Service started");
        return START_STICKY;
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private String createNotificationChannel(){
        NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
                NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);

        NotificationManager notificationManager = (NotificationManager)
                getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.createNotificationChannel(channel);
        return NOTIFICATION_CHANNEL_ID;
    }

    public class AppServiceBinder extends Binder {
        AppService getService() {
            return AppService.this;
        }
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return iBinder;
    }

    /**
     * 任务：创建WS连接客户端
     * 前台服务永不停止
     * WS连接永不停止
     * 只停止WEBRTC
     * @param intent
     * @param context
     * @return
     */
    public boolean initParams(Intent intent, Context context) {
        System.out.println("appservice inintParams");
        isRunning = true;
//        初始化临时邀请码
        this.tempInviteCode = settingsHelper.getInviteCode();
//        获取邀请码并初始化心跳连接
        startHeartClient();
        if (!startSignalClient())
            return false;
        this.intent = intent;
        this.context = context;
        webRtcManager = new WebRtcManager(intent, context, signalClient);
        UsbManage.init(this);
        ScreenManager.init(this);
        startServer(context);
        return isCastScreenRunning;
    }
    public String getWifiIP(Context context) {
        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        @SuppressLint("MissingPermission")
        int ipAddress = wifiManager.getConnectionInfo().getIpAddress();
        return String.format(
                "%d.%d.%d.%d",
                (ipAddress & 0xff),
                (ipAddress >> 8 & 0xff),
                (ipAddress >> 16 & 0xff),
                (ipAddress >> 24 & 0xff)
        );
    }

    public void startServer(Context context) {
        Server server = AndServer.webServer(context)
                .port(PORT_LOCAL_SERVER)
                .timeout(10, TimeUnit.SECONDS)
                .listener(new Server.ServerListener() {
                    @Override
                    public void onStarted() {
                        Handler handler = new Handler(Looper.getMainLooper());
                        handler.post(() -> Toast.makeText(context,
                                "服务器绑定地址:" + "http://" + getWifiIP(context) + ":"+PORT_LOCAL_SERVER,
                                Toast.LENGTH_SHORT).show());

                        System.out.println("服务器绑定地址:" + "http://" + getWifiIP(context) + ":"+PORT_LOCAL_SERVER);
                    }

                    @Override
                    public void onStopped() {}

                    @Override
                    public void onException(Exception e) {
                        e.printStackTrace();
                    }
                })
                .build();

        if (server != null) {
            server.startup();
        }
    }
    public void castScreenStop() {
        if (!isCastScreenRunning)
            return;
        heartClient.stop();
        webRtcManager.stop();
        isCastScreenRunning = false;
    }
    public void castScreeningStart(){
        if(isCastScreenRunning)
            return;
        heartClient.start();
        webRtcManager.start();
        JSONObject messageJson = new JSONObject();
        try {
            messageJson.put("type", "join");
            messageJson.put("data", tempInviteCode);
            String messageJsonStr = messageJson.toString();
            signalClient.send(messageJsonStr);
            Log.d(TAG, "Send JOIN: " + messageJsonStr);
//            webRtcManager.startRotationDetector(context);
        } catch (Exception e) {
            System.out.println(e);
            e.printStackTrace();
        }
        isCastScreenRunning = true;
    }
    public boolean isAllowInviteCode(){return allowInviteCode;};
    public boolean isCastScreenRunning() {
        return isCastScreenRunning;
    }
    public boolean startSignalClient() {
        System.out.println("启动signal-ws客户端");
        signalClient = new SignalClient(this.tempInviteCode, wsClientInterface);
        return signalClient.start();
    }
    public void signalClientStop(){
        signalClient.stop();
        signalClient = null;
    }
//    只有前台服务销毁时使用
    public void serverStop(){
        signalClientStop();
        castScreenStop();
    }
    public void startHeartClient() {
        System.out.println("启动heart-ws客户端");
        heartClient = new HeartClient(icinterface);
        heartClient.start();
    }
    public void editInviteCode(String inviteCode){
        this.tempInviteCode = inviteCode;
        heartClient.send(inviteCode);
    }
    private HeartClient.InviteCodeInterface icinterface = new HeartClient.InviteCodeInterface() {
        @Override
        public void onConnected() {
            tempInviteCode = settingsHelper.getInviteCode();
            if (!tempInviteCode.isEmpty()){
                heartClient.send(tempInviteCode);
            }
        }

        @Override
        public void onEditInviteCode() {
            settingsHelper.setInviteCode(tempInviteCode);
            allowInviteCode = true;
        }
    };
    private WebsocketClient.WsClientInterface wsClientInterface = new
            WebsocketClient.WsClientInterface() {
                @Override
                public void onOprEvent(String uri) {
                    if (webRtcManager == null)
                        return;
                    if (!settingsHelper.isRemoteControlEnabled()){
                        return;
                    }
//                    发送http请求
                    httpClient.get(CONTROL_BASE+uri,
                            new HttpCallBack() {
                                @Override
                                public void onSuccess(String t) {
                                    super.onSuccess(t);
                                }
                                @Override
                                public void onFailure(int errorNo, String strMsg) {
                                    super.onFailure(errorNo, strMsg);
                                    String errMsg = "控制模块异常";
                                    toast(errMsg);
                                    JSONObject messageJson = new JSONObject();
                                    JSONObject dataJson = new JSONObject();
                                    try {
                                        dataJson.put("code", 500);
                                        dataJson.put("msg", errMsg);

                                        messageJson.put("type", "oprcallback");
                                        messageJson.put("data", dataJson);
                                    } catch (JSONException e) {
                                        e.printStackTrace();
                                        return;
                                    }

                                    String messageJsonStr = messageJson.toString();
                                    signalClient.send(messageJsonStr);
                                }
                            });
                }
                @Override
                public void onSdp(JSONObject message) {
                    if (webRtcManager == null)
                        return;
                    webRtcManager.start();
//                    webRtcManager.onAnswerReceived(message);
                    webRtcManager.onOfferReceived(message);
                }
                @Override
                public void onIceCandidate(JSONObject message) {
                    if (webRtcManager == null)
                        return;
                    webRtcManager.onIceCandidateReceived(message);
                }

                @Override
                public void onFeedback(JSONObject message) {
                    if (webRtcManager == null)
                        return;
                    try {
                        if (message.getInt("code") == 200 ){
                            toast(message.getString("data"));
                        }
                    } catch (JSONException e) {
                        throw new RuntimeException(e);
                    }

                }

                //    断开与caller的webrtc连接
                @Override
                public void onBye() {
                    if (webRtcManager == null)
                        return;
                    webRtcManager.stop();
                }
            };
}
